﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using RibbonEditor.Rules;
using System.Windows.Forms;
using RibbonEditor.Forms.Rules;
using RibbonEditor.AppCode;
using RibbonEditor.Forms;

namespace RibbonEditor
{
    public class OrGroup: IXmlBuildable, IChildDeletable
    {
        public string Id { get; set; }
        public List<object> Rules { get; set; }

        public OrGroup()
        {
            this.Rules = new List<object>();
        }

        public OrGroup(XmlNode node)
            : this()
        {
            try
            {
                foreach (XmlNode ruleNode in node.ChildNodes)
                {
                    if (ruleNode.NodeType != XmlNodeType.Comment)
                    {
                        if (node.ParentNode.Name == "EnableRule")
                        {
                            IEnableRule rule = RuleHelper.GetIEnableRuleFromXml(ruleNode);
                            this.Rules.Add(rule);
                        }
                        else
                        {
                            IDisplayRule rule = RuleHelper.GetIDisplayRuleFromXml(ruleNode);
                            this.Rules.Add(rule);
                        }
                    }
                }
            }
            catch (Exception error)
            {
                MessageBox.Show("An error occured: " + error.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public void AddIEnableRule(IEnableRule ieRule)
        {
            this.Rules.Add(ieRule);
        }

        public void AddIDisplayRule(IDisplayRule ieRule)
        {
            this.Rules.Add(ieRule);
        }

        public void AddNode(XmlNode ruleNode)
        {
            try
            {
                XmlNode orNode = XmlHelper.AddNode(ruleNode, "Or");

                foreach (object rule in this.Rules)
                {
                    if (rule is IEnableRule)
                    {
                        ((IEnableRule)rule).AddNode(orNode);
                    }
                    else
                    {
                        ((IDisplayRule)rule).AddNode(orNode);
                    }
                }
            }
            catch (Exception error)
            {
                MessageBox.Show("An error occured: " + error.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        internal void BuildTreeViewElement(TreeNode parentNode)
        {
            try
            {
                TreeNode orNode = new TreeNode("Or");
                orNode.ContextMenuStrip = this.BuildContextMenu(orNode);
                orNode.Tag = this;

                foreach (object rule in this.Rules)
                {
                    if (rule is IEnableRule)
                    {
                        ((IEnableRule)rule).BuildTreeViewElement(orNode);
                    }
                    else
                    {
                        ((IDisplayRule)rule).BuildTreeViewElement(orNode);
                    }
                }

                parentNode.Nodes.Add(orNode);
            }
            catch (Exception error)
            {
                MessageBox.Show("An error occured: " + error.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private ContextMenuStrip BuildContextMenu(TreeNode relatedNode)
        {
            ToolStripMenuItem tsmi = new ToolStripMenuItem("Add Rule");
            ToolStripMenuItem tsmdx = new ToolStripMenuItem("Display Xml");
            ToolStripSeparator tsms = new ToolStripSeparator();
            ToolStripMenuItem tsmd = new ToolStripMenuItem("Delete");

            ContextMenuStrip cms = new ContextMenuStrip();
            cms.ItemClicked += new ToolStripItemClickedEventHandler(cms_ItemClicked);
            cms.Tag = relatedNode;
            cms.Items.Add(tsmi);
            cms.Items.Add(tsms);
            cms.Items.Add(tsmdx);
            cms.Items.Add(tsms);
            cms.Items.Add(tsmd);

            return cms;
        }

        void cms_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            try
            {
                string testString = "EnableRule|DisplayRule";
                TreeNode selectedNode = (TreeNode)e.ClickedItem.GetCurrentParent().Tag;

                switch (e.ClickedItem.Text)
                {
                    case "Display Xml":
                        {
                            XmlDocument doc = new XmlDocument();
                            doc.LoadXml("<root></root>");

                            ((IXmlBuildable)selectedNode.Tag).AddNode(doc.DocumentElement);

                            XmlContentDisplayDialog dialog = new XmlContentDisplayDialog(doc.DocumentElement.InnerXml);
                            dialog.StartPosition = FormStartPosition.CenterParent;
                            dialog.ShowDialog();
                        }
                        break;
                    case "Delete":
                        {
                            selectedNode.TreeView.SelectedNode = selectedNode.Parent;
                            UIActionHelper.Delete(selectedNode);
                            //selectedNode.Parent.Nodes.Remove(selectedNode);

                        }
                        break;
                    default:
                        {
                            TreeNode currentNode = selectedNode;

                            while (!testString.Contains(currentNode.Text))
                            {
                                currentNode = currentNode.Parent;
                            }

                            if (currentNode.Text == "EnableRule")
                            {
                                selectedNode = (TreeNode)e.ClickedItem.GetCurrentParent().Tag;
                                RuleSelectionDialog rsDialog = new RuleSelectionDialog(RuleSelectionDialog.RuleType.OrGroupFromEnable);
                                rsDialog.StartPosition = FormStartPosition.CenterParent;

                                if (rsDialog.ShowDialog() == DialogResult.OK)
                                {
                                    IEnableRule selectedRule = (IEnableRule)rsDialog.SelectedRule;

                                    this.Rules.Add(selectedRule);
                                    selectedRule.BuildTreeViewElement(selectedNode);
                                }
                            }
                            else
                            {
                                RuleSelectionDialog rsDialog = new RuleSelectionDialog(RuleSelectionDialog.RuleType.OrGroupFromDisplay);

                                if (rsDialog.ShowDialog() == DialogResult.OK)
                                {
                                    IDisplayRule selectedRule = (IDisplayRule)rsDialog.SelectedRule;

                                    this.Rules.Add(selectedRule);
                                    selectedRule.BuildTreeViewElement(selectedNode);
                                }
                            }
                        }
                        break;
                }
            }
            catch (Exception error)
            {
                MessageBox.Show("An error occured: " + error.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #region IChildDeletable Members

        public void DeleteChild(object o)
        {
            try
            {
                if (o is IEnableRule || o is IDisplayRule)
                {
                    this.Rules.Remove(o);
                }
                else
                {
                    throw new Exception("Unsupported child type: " + o.GetType());
                }
            }
            catch (Exception error)
            {
                MessageBox.Show("An error occured: " + error.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion
    }
}
